function E = compute_Canny( P )


X=P;
x=double(X);
[C,L]=size(x);

%手动计算出来的7×7的高度对称高斯滤波模板，主要用于canny算子的计算
div = 12.2791;
G = [    0.0111    0.0388    0.0821    0.1054    0.0821    0.0388    0.0111;
    0.0388    0.1353    0.2865    0.3679    0.2865    0.1353    0.0388;
    0.0821    0.2865    0.6065    0.7788    0.6065    0.2865    0.0821;
    0.1054    0.3679    0.7788    1.0000    0.7788    0.3679    0.1054;
    0.0821    0.2865    0.6065    0.7788    0.6065    0.2865    0.0821;
    0.0388    0.1353    0.2865    0.3679    0.2865    0.1353    0.0388;
    0.0111    0.0388    0.0821    0.1054    0.0821    0.0388    0.0111];

%必要的变量声明
out = zeros(C,L);


factor = 2;
limit = 3.5;
range = zeros(C, L);   %幅度矩阵
tanangle = zeros(C, L); %角度矩阵(此处采用角度，也可直接用正切来比较)
%%%%%%%%%%%%%%%
%%高斯滤波
for I = 4:C-3
    for J = 4:L-3
        result = 0;
        for u = -3:3
            for v = -3:3
                result = result + x(I+u, J+v)*G(u+4,v+4);
            end
        end
        x(I,J) = result/div;
    end
end
%%一阶差分卷积模板
for I = 1:C-1
    for J = 1:L-1
        result1 = x(I+1,J)+x(I+1,J+1)-x(I,J)-x(I,J+1);
        result2 = x(I,J)+x(I+1,J)-x(I,J+1)-x(I+1,J+1);
        result = (result1*result1+result2*result2)^0.5;
        result=result/factor;
        range(I, J) = round(result);    %求出梯度大小
        if result1 == 0
            result1 = 0.000001;
        end
        tanangle(I, J) = atan(result2/result1);  %求出梯度的夹角
    end
end

%%非极大值抑制
% 在[-pi/2, pi/2]上讨论，分四个方向
rangetemp = range;
for I = 2:C-1
    for J = 2:L-1
        if tanangle(I, J) >= -pi/8 && tanangle(I, J) < pi/8 && ( rangetemp(I, J)...
                <=  rangetemp(I+1, J) || rangetemp(I, J) <=  rangetemp(I-1, J))
            range(I, J) = 0;
        end
        if tanangle(I, J) >= pi/8 && tanangle(I, J) < 3*pi/8 && ( rangetemp(I, J)...
                <=  rangetemp(I-1, J+1) ||  rangetemp(I, J) <=  rangetemp(I+1, J-1))
            range(I, J) = 0;
        end
        if tanangle(I, J) >= -3*pi/8 && tanangle(I, J) < -pi/8 && ( rangetemp(I, J)...
                <=  rangetemp(I-1, J-1) ||  rangetemp(I, J) <=  rangetemp(I+1, J+1))
            range(I, J) = 0;
        end
        if (tanangle(I, J) < -3*pi/8 || tanangle(I, J) >=  3*pi/8) && ( rangetemp(I, J)...
                <=  rangetemp(I-1, J) ||  rangetemp(I, J) <=  rangetemp(I+1, J))
            range(I, J) = 0;
        end
    end
end
%%阈值化，第一次取边缘点
for I = 2:C-1
    for J = 2:L-1
        if range(I, J) > limit*2
            out(I, J) = 256;
        end
    end
end
%做100次扫描确保将边缘都连接起来，第二次取边缘点
for K = 1:100
    for I = 2:C-1
        for J = 2:L-1
            if range(I, J) > limit && range(I, J) <= limit*2
                if  out(I-1, J) == 256 || out(I-1, J-1) == 256 ||...    %边缘连接
                        out(I-1, J+1) == 256 ||  out(I+1, J-1) == 256 ||...
                        out(I+1, J) == 256 ||  out(I+1, J+1) == 256 ||...
                        out(I, J-1) == 256 ||  out(I, J+1) == 256
                    
                    out(I, J) = 256;
                end
            end
        end
    end
end


E = uint8(out)-1;

end